home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1997 June
/
EnigmA AMIGA RUN 19 (1997)(G.R. Edizioni)(IT)[!][issue 1997-06][EAR-CD III].iso
/
games
/
interactivefiction
/
agt
/
source
/
os_amiga.c
< prev
Wrap
C/C++ Source or Header
|
1996-10-31
|
14KB
|
643 lines
/* os_amiga.c -- Interface routine for the Amiga. */
/* Written by David Kinder. */
#include <proto/asl.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/gadtools.h>
#include <proto/icon.h>
#include <proto/intuition.h>
#include <exec/exec.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <time.h>
#include "agtread.h"
#include "uagt.h"
#define SHIFT (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)
#define HISTORY_SIZE 10
enum chars
{ CHAR_LEFT = 0x100,
CHAR_SHIFTLEFT,
CHAR_RIGHT,
CHAR_SHIFTRIGHT,
CHAR_UP,
CHAR_DOWN };
extern struct Library *IntuitionBase;
struct Screen *Screen;
struct Window *Window;
struct Window *OldWindowPtr;
struct RastPort *RPort;
struct Menu *Menus;
struct Process *ThisProcess;
struct FileRequester *FileReq;
APTR Visual;
char *History[HISTORY_SIZE];
char Version[] = "$VER:AGiliTy 0.3 (31.10.96)";
int scroll_count;
int screen_height;
int box,boxx;
void print_statline(void);
void busy_pointer(int busy);
void draw_cursor(void);
void get_string(char *buffer, int len);
void add_history(char *buffer);
int use_history(char *buffer, int hpos, int left);
void file_req(char *s,char *title,char *pattern,char *dir,ULONG save);
void agt_delay(int n)
{
print_statline();
Delay(50*n);
}
void agt_tone(int hz,int ms)
{
}
int agt_rand(int a,int b)
{
return a+(rand()>>2)%(b-a+1);
}
char *agt_input(int in_type)
{
char *s;
scroll_count = 0;
print_statline();
s = rmalloc(256);
get_string(s,256);
if (script_on) fprintf(scriptfile,"%s",s);
agt_newline();
return s;
}
char agt_getkey(bool echo_char)
{
char s[2];
int c = 128;
print_statline();
s[1] = '\0';
while (c >= 128) c = get_character();
if (echo_char && c > 32)
{
SetAPen(RPort,2);
s[0] = c;
agt_puts(s);
agt_newline();
SetAPen(RPort,1);
}
return c;
}
void agt_textcolor(int c)
{
switch (c)
{
case -1:
while ((RPort->AlgoStyle & FSF_BOLD) == 0)
SetSoftStyle(RPort,RPort->AlgoStyle|FSF_BOLD,AskSoftStyle(RPort));
break;
case -2:
while (RPort->AlgoStyle != 0)
SetSoftStyle(RPort,FS_NORMAL,AskSoftStyle(RPort));
break;
}
}
void agt_statline(const char *s)
{
int x,y;
SetAPen(RPort,2);
SetBPen(RPort,3);
x = RPort->cp_x;
y = RPort->cp_y;
Move(RPort,0,RPort->TxBaseline);
Text(RPort,s,strlen(s));
Move(RPort,x,y);
SetAPen(RPort,1);
SetBPen(RPort,0);
}
void agt_clrscr(void)
{
SetAPen(RPort,0);
RectFill(RPort,
0,RPort->TxHeight,
Window->Width-1,(screen_height*RPort->TxHeight)-1);
SetAPen(RPort,1);
Move(RPort,0,RPort->TxHeight);
curr_x = 0;
if (script_on) fprintf(scriptfile,"\n\n\n\n");
scroll_count = 0;
}
void agt_puts(const char *s)
{
Move(RPort,RPort->cp_x,RPort->cp_y+RPort->TxBaseline);
Text(RPort,s,strlen(s));
Move(RPort,RPort->cp_x,RPort->cp_y-RPort->TxBaseline);
if (RPort->cp_x/RPort->TxWidth >= screen_width) RPort->cp_x = 0;
curr_x = RPort->cp_x/RPort->TxWidth;
if (script_on) fprintf(scriptfile,"%s",s);
}
void agt_newline(void)
{
if (RPort->cp_y/RPort->TxHeight >= screen_height-1)
{
ClipBlit(RPort,0,RPort->TxHeight*2,
RPort,0,RPort->TxHeight,
Window->Width,(screen_height-2)*RPort->TxHeight,0xC0);
SetAPen(RPort,0);
RectFill(RPort,
0,(screen_height-1)*RPort->TxHeight,
Window->Width-1,(screen_height*RPort->TxHeight)-1);
SetAPen(RPort,1);
Move(RPort,boxx,(screen_height-1)*RPort->TxHeight);
}
else Move(RPort,boxx,RPort->cp_y+RPort->TxHeight);
if (box == 0)
{
scroll_count++;
if (scroll_count >= screen_height-2)
{
Move(RPort,0,RPort->cp_y+RPort->TxBaseline);
Text(RPort," --MORE--",10);
Move(RPort,RPort->cp_x,RPort->cp_y-RPort->TxBaseline);
agt_getkey(0);
Move(RPort,0,RPort->cp_y+RPort->TxBaseline);
Text(RPort," ",10);
Move(RPort,0,RPort->cp_y-RPort->TxBaseline);
scroll_count = 0;
}
}
curr_x = 0;
if (script_on) fprintf(scriptfile,"\n");
}
void init_interface(void)
{
struct Screen *default_pub_screen;
static WORD screen_pens[] = { -1 };
static struct NewMenu menus[] =
{{ NM_TITLE,"Project",0,0,0,0 },
{ NM_ITEM,"About...","?",0,0,0 },
{ NM_ITEM,"Quit","Q",0,0,0 },
{ NM_END,0,0,0,0 }};
srand(time(0));
script_on = 0;
scriptfile = 0;
center_on = par_fill_on = 0;
scroll_count = 0;
debugfile = stderr;
DEBUG_OUT = 0;
if (IntuitionBase->lib_Version < 37) exit(0);
if ((default_pub_screen = LockPubScreen(0)) == 0) exit(0);
if ((Screen = OpenScreenTags(0,
SA_Pens,screen_pens,
SA_SysFont,1,
SA_DisplayID,GetVPModeID(&default_pub_screen->ViewPort),
SA_Overscan,OSCAN_TEXT,
SA_Depth,2,
SA_Type,CUSTOMSCREEN|AUTOSCROLL,
SA_Title,"AGiliTy",TAG_DONE)) == 0) exit(0);
UnlockPubScreen(0,default_pub_screen);
if ((Window = OpenWindowTags(0,
WA_Left,0,
WA_Top,Screen->BarHeight+1,
WA_Width,Screen->Width,
WA_Height,Screen->Height-Screen->BarHeight-1,
WA_Flags,
WFLG_ACTIVATE|WFLG_SMART_REFRESH|WFLG_NEWLOOKMENUS|WFLG_BORDERLESS|
WFLG_BACKDROP,
WA_IDCMP,IDCMP_VANILLAKEY|IDCMP_RAWKEY|IDCMP_MENUPICK,
WA_CustomScreen,Screen,TAG_DONE)) == 0) exit(0);
ThisProcess = (struct Process *)FindTask(0);
OldWindowPtr = ThisProcess->pr_WindowPtr;
ThisProcess->pr_WindowPtr = Window;
if ((Visual = GetVisualInfo(Screen,TAG_DONE)) == 0) exit(0);
if ((Menus = CreateMenus(menus,GTMN_NewLookMenus,1,TAG_DONE)) == 0)
exit(0);
LayoutMenus(Menus,Visual,GTMN_NewLookMenus,1,TAG_DONE);
SetMenuStrip(Window,Menus);
RPort = Window->RPort;
SetDrMd(RPort,JAM2);
SetAPen(RPort,1);
SetBPen(RPort,0);
screen_height = Window->Height/RPort->TxHeight;
screen_width = Window->Width/RPort->TxWidth;
status_width = screen_width;
agt_clrscr();
}
void close_interface(void)
{
if (scriptfile != 0) fclose(scriptfile);
}
__autoexit void clear_up(void)
{
int i;
for (i = 0; i < HISTORY_SIZE; i++)
if (History[i] != NULL) FreeVec(History[i]);
if (FileReq) FreeAslRequest(FileReq);
if (Menus) FreeMenus(Menus);
if (Visual) FreeVisualInfo(Visual);
if (ThisProcess) ThisProcess->pr_WindowPtr = OldWindowPtr;
if (Window) CloseWindow(Window);
if (Screen) CloseScreen(Screen);
}
int get_character(void)
{
struct IntuiMessage *imsg;
ULONG class;
UWORD code, qualifier;
static struct EasyStruct requester =
{ sizeof(struct EasyStruct),0,"AGiliTy",
"AGiliTy AGT Interpreter 0.3ß\n"
"© 1996 by Robert Masenten\n\n"
"Amiga Version by David Kinder","Continue" };
draw_cursor();
for (;;)
{
while (imsg = (struct IntuiMessage *)GetMsg(Window->UserPort))
{
class = imsg->Class;
code = imsg->Code;
qualifier = imsg->Qualifier;
ReplyMsg((struct Message *)imsg);
switch (class)
{
case IDCMP_VANILLAKEY:
draw_cursor();
return code;
break;
case IDCMP_RAWKEY:
switch (code)
{
case 0x4C:
draw_cursor();
return CHAR_UP;
break;
case 0x4D:
draw_cursor();
return CHAR_DOWN;
break;
case 0x4E:
draw_cursor();
return (qualifier & SHIFT) ? CHAR_SHIFTRIGHT : CHAR_RIGHT;
break;
case 0x4F:
draw_cursor();
return (qualifier & SHIFT) ? CHAR_SHIFTLEFT : CHAR_LEFT;
break;
}
break;
case IDCMP_MENUPICK:
if (MENUNUM(code) == 0)
{
switch (ITEMNUM(code))
{
case 0:
busy_pointer(1);
EasyRequest(Window,&requester,0);
busy_pointer(0);
break;
case 1:
exit(0);
break;
}
}
break;
}
}
WaitPort(Window->UserPort);
}
}
void busy_pointer(int busy)
{
if (IntuitionBase->lib_Version >= 39)
SetWindowPointer(Window,WA_BusyPointer,busy,TAG_DONE);
}
void draw_cursor(void)
{
SetDrMd(RPort,COMPLEMENT);
RectFill(RPort,
RPort->cp_x,RPort->cp_y,
RPort->cp_x+RPort->TxWidth-1,RPort->cp_y+RPort->TxHeight-1);
SetDrMd(RPort,JAM2);
}
void get_string(char *buffer, int len)
{
int c, end = 0, cursor = 0, hpos = -1;
char co;
UWORD left;
*buffer = '\0';
left = RPort->cp_x;
SetAPen(RPort,2);
for (;;)
{
c = get_character();
switch (c)
{
case 0x0D:
*(buffer+end) = '\0';
add_history(buffer);
*(buffer+end) = '\n';
*(buffer+end+1) = '\0';
SetAPen(RPort,1);
return;
break;
case 0x7F:
if ((end > 0) && (cursor < end))
{
memmove(buffer+cursor,buffer+cursor+1,end-cursor+1);
ClipBlit(RPort,RPort->cp_x+RPort->TxWidth,RPort->cp_y,
RPort,RPort->cp_x,RPort->cp_y,
Window->Width-RPort->cp_x-RPort->TxWidth,
RPort->TxHeight,0xC0);
end--;
}
break;
case 0x08:
if ((end > 0) && (cursor > 0))
{
memmove(buffer+cursor-1,buffer+cursor,end-cursor+1);
ClipBlit(RPort,RPort->cp_x,RPort->cp_y,
RPort,RPort->cp_x-RPort->TxWidth,RPort->cp_y,
Window->Width-RPort->cp_x-RPort->TxWidth,
RPort->TxHeight,0xC0);
Move(RPort,RPort->cp_x-RPort->TxWidth,RPort->cp_y);
end--;
cursor--;
}
break;
case CHAR_LEFT:
if (cursor > 0)
{
cursor--;
Move(RPort,RPort->cp_x-RPort->TxWidth,RPort->cp_y);
}
break;
case CHAR_SHIFTLEFT:
if (cursor > 0)
{
Move(RPort,left,RPort->cp_y);
cursor = 0;
}
break;
case CHAR_RIGHT:
if (cursor < end)
{
cursor++;
Move(RPort,RPort->cp_x+RPort->TxHeight,RPort->cp_y);
}
break;
case CHAR_SHIFTRIGHT:
if (cursor < end)
{
Move(RPort,RPort->cp_x+(RPort->TxWidth*(end-cursor)),RPort->cp_y);
cursor = end;
}
break;
case CHAR_UP:
if ((hpos < HISTORY_SIZE-1) && (History[hpos+1]))
cursor = end = use_history(buffer,++hpos,left);
break;
case CHAR_DOWN:
if ((hpos > 0) && (History[hpos-1]))
cursor = end = use_history(buffer,--hpos,left);
else
cursor = end = use_history(buffer,-1,left);
break;
default:
if ((end < len-3) && (isprint((unsigned char)c) != 0) && ( c < 128)
&& (RPort->cp_x+(RPort->TxWidth*(end-cursor+2)) < Window->Width))
{
memmove(buffer+cursor+1,buffer+cursor,end-cursor+1);
*(buffer+cursor++) = c;
ClipBlit(RPort,RPort->cp_x,RPort->cp_y,
RPort,RPort->cp_x+RPort->TxWidth,RPort->cp_y,
Window->Width-RPort->cp_x-RPort->TxWidth,
RPort->TxHeight,0xC0);
end++;
Move(RPort,RPort->cp_x,RPort->cp_y+RPort->TxBaseline);
co = c;
Text(RPort,&co,1);
Move(RPort,RPort->cp_x,RPort->cp_y-RPort->TxBaseline);
}
break;
}
}
}
void add_history(char *buffer)
{
char *hist;
int i;
if (strcmp(buffer,"") == 0) return;
if ((hist = AllocVec(strlen(buffer)+1,MEMF_CLEAR)) == NULL) return;
strncpy(hist,buffer,strlen(buffer));
if (History[HISTORY_SIZE-1] != NULL) FreeVec(History[HISTORY_SIZE-1]);
for (i = HISTORY_SIZE-1; i > 0; i--) History[i] = History[i-1];
History[0] = hist;
}
int use_history(char *buffer, int hpos, int left)
{
strcpy(buffer,(hpos > -1) ? History[hpos] : "");
SetAPen(RPort,0);
RectFill(RPort,left,RPort->cp_y,
Window->Width-1,RPort->cp_y+RPort->TxHeight-1);
SetAPen(RPort,2);
Move(RPort,left,RPort->cp_y);
agt_puts(buffer);
return strlen(buffer);
}
void file_req(char *s,char *title,char *pattern,char *dir,ULONG save)
{
if (FileReq == NULL)
{
if ((FileReq = AllocAslRequestTags(ASL_FileRequest,
ASLFR_SleepWindow,1,
ASLFR_RejectIcons,1,
ASLFR_InitialDrawer,dir,TAG_DONE)) == NULL) exit(0);
}
if (AslRequestTags(FileReq,
ASLFR_Window,Window,
ASLFR_DoPatterns,pattern == NULL ? 0 : 1,
ASLFR_InitialPattern,pattern == NULL ? "#?" : pattern,
ASLFR_InitialFile,"",
ASLFR_TitleText,title,
ASLFR_DoSaveMode,save,TAG_DONE))
{
strcpy(s,FileReq->fr_Drawer);
AddPart(s,FileReq->fr_File,256);
}
else strcpy(s,"");
}
wbmain(struct WBStartup *wb_msg)
{
struct DiskObject *icon;
char file_name[256], start_dir[256];
char *args[2], *dir, *file, *ext;
args[0] = wb_msg->sm_ArgList[0].wa_Name;
args[1] = file_name;
strcpy(start_dir,"");
if (icon = GetDiskObject(args[0]))
{
if (dir = FindToolType(icon->do_ToolTypes,"DIR")) strcpy(start_dir,dir);
FreeDiskObject(icon);
}
file_req(file_name,"Select an AGT Game","#?.da1",start_dir,0);
file = FilePart(file_name);
if (ext = strrchr(file,'.')) *ext = '\0';
main(2,args);
exit(0);
}
FILE *get_user_file(int ft)
{
char *fname, *otype, *title;
char *p, *q;
int save;
FILE *fd;
switch (ft)
{
case 0:
title = "Script File";
save = 1;
otype = "a";
break;
case 1:
title = "Save Game";
save = 1;
otype = "wb";
break;
case 2:
title = "Restore Game";
save = 0;
otype = "rb";
break;
case 3:
title = "Read Log";
save = 0;
otype = "r";
break;
case 4:
title = "Write Log";
save = 1;
otype = "w";
break;
default:
writeln("<INT ERR: invalid file type>");
return NULL;
}
fname = rmalloc(256);
file_req(fname,title,NULL,"",save);
for(p = fname; isspace(*p); p++);
for(q = fname; *p!=0; p++, q++) *q=*p;
*q = 0;
if (q==fname)
{
writeln("Never mind.");
rfree(fname);
return NULL;
}
if (otype[0] == 'w')
{
fd = fopen(fname,"r");
if (fd)
{
fclose(fd);
if (!yesno("This file already exists; overwrite?"))
{
rfree(fname);
return NULL;
}
}
}
fd = fopen(fname,otype);
if (fd == NULL) writeln("Cannot open file.");
rfree(fname);
return fd;
}
bool agt_option(int optnum, char *optstr[], bool setflag)
{
return 0;
}
FILE *agt_globalfile(int fid)
{
if (fid == 0)
return fopen("agil.cfg","r");
return NULL;
}
void agt_makebox(int width, int height, unsigned long flags)
{
box = 1;
boxx = flags & TB_NOCENT ? 0 : ((screen_width-width)/2)*RPort->TxWidth;
if (flags & TB_TTL)
Move(RPort,boxx,(((screen_height-height)/4)*RPort->TxHeight));
else
Move(RPort,boxx,RPort->cp_y-(screen_height-height)*RPort->TxHeight);
}
void agt_qnewline(void)
{
agt_newline();
}
void agt_endbox(void)
{
box = 0;
boxx = 0;
agt_newline();
}